package com.youlai.boot.factory.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.youlai.boot.common.exception.BusinessException;
import com.youlai.boot.common.result.ResultCode;
import com.youlai.boot.common.util.ResponseUtils;
import com.youlai.boot.core.security.util.SecurityUtils;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.youlai.boot.factory.mapper.TrialApplicationsMapper;
import com.youlai.boot.factory.service.TrialApplicationsService;
import com.youlai.boot.factory.model.entity.TrialApplications;
import com.youlai.boot.factory.model.form.TrialApplicationsForm;
import com.youlai.boot.factory.model.form.TrialApplicationsAuditForm;
import com.youlai.boot.factory.model.query.TrialApplicationsQuery;
import com.youlai.boot.factory.model.vo.TrialApplicationsVO;
import com.youlai.boot.factory.converter.TrialApplicationsConverter;
import com.youlai.boot.factory.enums.AuditStatusEnum;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import java.time.LocalDateTime;

/**
 * 试用申请单服务实现类
 *
 * @author youlaitech
 * @since 2025-11-11 10:19
 */
@Service
@RequiredArgsConstructor
public class TrialApplicationsServiceImpl extends ServiceImpl<TrialApplicationsMapper, TrialApplications> implements TrialApplicationsService {

    private final TrialApplicationsConverter trialApplicationsConverter;

    /**
    * 获取试用申请单分页列表
    *
    * @param queryParams 查询参数
    * @return {@link IPage<TrialApplicationsVO>} 试用申请单分页列表
    */
    @Override
    public IPage<TrialApplicationsVO> getTrialApplicationsPage(TrialApplicationsQuery queryParams) {
        Page<TrialApplicationsVO> pageVO = this.baseMapper.getTrialApplicationsPage(
                new Page<>(queryParams.getPageNum(), queryParams.getPageSize()),
                queryParams
        );
        return pageVO;
    }

    /**
     * 获取试用申请单表单数据
     *
     * @param id 试用申请单ID
     * @return 试用申请单表单数据
     */
    @Override
    public TrialApplicationsForm getTrialApplicationsFormData(Long id) {
        TrialApplications entity = this.getById(id);
        return trialApplicationsConverter.toForm(entity);
    }

    /**
     * 新增试用申请单
     *
     * @param formData 试用申请单表单对象
     * @return 是否新增成功
     */
    @Override
    public boolean saveTrialApplications(TrialApplicationsForm formData) {
        // 拿到上下文中的用户信息
        String openId = SecurityUtils.getOpenId();

        formData.setApplicantOpenid(openId);
        TrialApplications entity = trialApplicationsConverter.toEntity(formData);
        return this.save(entity);
    }


    /**
     * 更新试用申请单
     *
     * @param id   试用申请单ID
     * @param formData 试用申请单表单对象
     * @return 是否修改成功
     */
    @Override
    public boolean updateTrialApplications(Long id,TrialApplicationsForm formData) {
        TrialApplications entity = trialApplicationsConverter.toEntity(formData);
        return this.updateById(entity);
    }

    /**
     * 删除试用申请单
     *
     * @param ids 试用申请单ID，多个以英文逗号(,)分割
     * @return 是否删除成功
     */
    @Override
    public boolean deleteTrialApplicationss(String ids) {
        Assert.isTrue(StrUtil.isNotBlank(ids), "删除的试用申请单数据为空");
        // 逻辑删除
        List<Long> idList = Arrays.stream(ids.split(","))
                .map(Long::parseLong)
                .toList();
        return this.removeByIds(idList);
    }


    /**
     * 获取试用申请单表单数据
     *
     * @return 试用申请单表单数据
     */
    @Override
    public TrialApplicationsForm getTrialApplicationsDetailByOpenId() {
        //先去获取当前用户的openId
        String openId = SecurityUtils.getOpenId();
        TrialApplications entity = this.getOne(new QueryWrapper<TrialApplications>().eq("applicant_openid", openId));
        return trialApplicationsConverter.toForm(entity);
    }

    /**
     * 申请试用表单（同一个openid只能新增一次，如果存在则改为修改）
     * 待审核状态不能修改
     *
     * @param formData 试用申请单表单对象
     * @return 是否操作成功
     */
    @Override
    public boolean applyTrialApplication(TrialApplicationsForm formData) {
        // 获取当前用户的openId
        String openId = SecurityUtils.getOpenId();
        if (StrUtil.isBlank(openId)) {
            throw new BusinessException(ResultCode.USER_NOT_EXIST, "未获取到用户信息，请重新登录");
        }

        // 根据openid查询是否已存在申请
        TrialApplications existingApplication = this.getOne(
                new LambdaQueryWrapper<TrialApplications>()
                        .eq(TrialApplications::getApplicantOpenid, openId)
                        .last("LIMIT 1")
        );

        if (existingApplication != null) {
            // 已存在申请，检查状态
            Integer status = existingApplication.getApplicationStatus();
            Integer pendingStatus = Integer.parseInt(AuditStatusEnum.PENDING.getValue());
            if (status == null || status.equals(pendingStatus)) {
                // 待审核状态不能修改
                throw new BusinessException(ResultCode.USER_REQUEST_PARAMETER_ERROR, "您的申请正在审核中，无法修改，请等待审核结果");
            }
            // 已通过或已拒绝可以修改，更新申请
            formData.setId(existingApplication.getId());
            formData.setApplicantOpenid(openId);
            // 修改时重置状态为待审核
            formData.setApplicationStatus(pendingStatus);
            TrialApplications entity = trialApplicationsConverter.toEntity(formData);
            return this.updateById(entity);
        } else {
            // 不存在申请，新增
            formData.setApplicantOpenid(openId);
            // 新增时设置状态为待审核
            formData.setApplicationStatus(Integer.parseInt(AuditStatusEnum.PENDING.getValue()));
            TrialApplications entity = trialApplicationsConverter.toEntity(formData);
            return this.save(entity);
        }
    }

    /**
     * 审核试用申请单（只能编辑审核备注、审核状态和审核时间）
     *
     * @param id 试用申请单ID
     * @param auditForm 审核表单对象
     * @return 是否审核成功
     */
    @Override
    public boolean auditTrialApplication(Long id, TrialApplicationsAuditForm auditForm) {
        // 验证申请单是否存在
        TrialApplications existingApplication = this.getById(id);
        if (existingApplication == null) {
            throw new BusinessException(ResultCode.USER_RESOURCE_NOT_FOUND, "申请单不存在");
        }

        // 使用 LambdaUpdateWrapper 只更新审核相关字段
        LambdaUpdateWrapper<TrialApplications> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(TrialApplications::getId, id)
                .set(TrialApplications::getApplicationStatus, auditForm.getApplicationStatus())
                .set(TrialApplications::getReviewRemark, auditForm.getReviewRemark())
                .set(TrialApplications::getReviewTime, LocalDateTime.now());


        // 设置更新人（可选，如果有当前用户信息）
        // updateWrapper.set(TrialApplications::getUpdateBy, SecurityUtils.getUsername());

        return this.update(updateWrapper);
    }
}
